import express from "express";
import Result from "../../common/result.js";
import { UPLOAD_PATH, OUTPUT_PATH, taskList } from "../../const/index.js";
import { CODEC_MAP } from "../../const/index.js";
import path from "path";
import Ffmpeg from "fluent-ffmpeg";
import { nanoid } from "nanoid";
import { spawn } from "child_process";
import fse from "fs-extra";

const videoRouter = express.Router();

videoRouter.post("/convert", async (req, res) => {
  try {
    const { convertOption, fileHash, fileName } = req.body;
    const { targetFormat } = convertOption;
    const outputPath = path.join(OUTPUT_PATH, `${fileHash}.${targetFormat}`);
    const filePath = path.join(
      UPLOAD_PATH,
      `${fileHash}${path.extname(fileName)}`
    );
    const command = Ffmpeg(filePath);
    command.outputOptions(CODEC_MAP[targetFormat].options);
    command.on("error", (error, _stdout, _stderr) => {
      throw new Error(error);
    });
    command.saveToFile(outputPath);
    command.run();
    const taskId = nanoid();
    taskList.set(taskId, {
      fileHash,
      fileName,
      fileType: targetFormat,
      done: false,
    });
    command.on("end", (_stdout, _stderr) => {
      taskList.get(taskId).done = true;
    });
    return res.send(Result.success({ taskId }, "视频转换任务已经开始..."));
  } catch (error) {
    return Result.error(
      { message: "服务器内部错误", error },
      "视频转换失败，发生了未知错误",
      101
    );
  }
});

videoRouter.post("/merge", async (req, res) => {
  try {
    const { videoList, fileName, mergeOption } = req.body;
    const { targetFormat } = mergeOption;
    const taskId = nanoid();
    const filePath = path.join(OUTPUT_PATH, `./${taskId}.${targetFormat}`);
    taskList.set(taskId, {
      fileHash: taskId,
      fileName,
      fileType: targetFormat,
      done: false,
    });
    let fileListContent = "";
    for (const video of videoList) {
      fileListContent += `file '${path.join(
        UPLOAD_PATH,
        `${video.fileHash}.${video.fileType}`
      )}'\n`;
    }
    fse.writeFileSync(
      path.join(OUTPUT_PATH, `./${taskId}.txt`),
      fileListContent
    );
    //合并视频
    const process = spawn("ffmpeg", [
      "-f",
      "concat",
      "-safe",
      "0",
      "-i",
      `${OUTPUT_PATH}/${taskId}.txt`,
      "-c",
      "copy",
      filePath,
    ]);
    process.on("close", () => {
      fse.remove(path.join(OUTPUT_PATH, `./${taskId}.txt`));
      taskList.get(taskId).done = true;
    });
    process.on("error", (error) => {
      console.log(error);
    });
    return res.send(Result.success({ taskId }, "视频合并任务已经开始..."));
  } catch (error) {
    console.log(error);
    return Result.error(
      { message: "服务器内部错误", error },
      "视频合并失败，发生了未知错误",
      101
    );
  }
});

export default videoRouter;
